package tools.jackson.module.kotlin.kogeraIntegration.deser.valueClass.parameterSize.nullablePrimitive

import tools.jackson.module.kotlin.assertReflectEquals
import tools.jackson.module.kotlin.callPrimaryConstructor
import tools.jackson.module.kotlin.defaultMapper
import tools.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullablePrimitive
import tools.jackson.module.kotlin.readValue
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test

/**
 * Up to argument size 32 there is one mask argument for the default argument,
 * 33 ~ 64 there are two, and 65 there are three, so each boundary value is tested.
 * Also, the maximum size of arguments that can be set by a constructor
 * that includes a value class as an argument is 253 (one less by DefaultConstructorMarker), so test that case as well.
 */
class DeserializeByConstructorWithoutDefaultArgumentsTest {
    data class Dst32(
        val p00: NullablePrimitive,
        val p01: NullablePrimitive,
        val p02: NullablePrimitive,
        val p03: NullablePrimitive,
        val p04: NullablePrimitive,
        val p05: NullablePrimitive,
        val p06: NullablePrimitive,
        val p07: NullablePrimitive,
        val p08: NullablePrimitive,
        val p09: NullablePrimitive,
        val p10: NullablePrimitive,
        val p11: NullablePrimitive,
        val p12: NullablePrimitive,
        val p13: NullablePrimitive,
        val p14: NullablePrimitive,
        val p15: NullablePrimitive,
        val p16: NullablePrimitive,
        val p17: NullablePrimitive,
        val p18: NullablePrimitive,
        val p19: NullablePrimitive,
        val p20: NullablePrimitive,
        val p21: NullablePrimitive,
        val p22: NullablePrimitive,
        val p23: NullablePrimitive,
        val p24: NullablePrimitive,
        val p25: NullablePrimitive,
        val p26: NullablePrimitive,
        val p27: NullablePrimitive,
        val p28: NullablePrimitive,
        val p29: NullablePrimitive,
        val p30: NullablePrimitive,
        val p31: NullablePrimitive
    )

    @Test
    fun test32() {
        val expected = callPrimaryConstructor<Dst32> { NullablePrimitive(it.index) }
        val src = defaultMapper.writeValueAsString(expected)
        Assertions.assertEquals(expected, defaultMapper.readValue<Dst32>(src))
    }

    data class Dst33(
        val p00: NullablePrimitive,
        val p01: NullablePrimitive,
        val p02: NullablePrimitive,
        val p03: NullablePrimitive,
        val p04: NullablePrimitive,
        val p05: NullablePrimitive,
        val p06: NullablePrimitive,
        val p07: NullablePrimitive,
        val p08: NullablePrimitive,
        val p09: NullablePrimitive,
        val p10: NullablePrimitive,
        val p11: NullablePrimitive,
        val p12: NullablePrimitive,
        val p13: NullablePrimitive,
        val p14: NullablePrimitive,
        val p15: NullablePrimitive,
        val p16: NullablePrimitive,
        val p17: NullablePrimitive,
        val p18: NullablePrimitive,
        val p19: NullablePrimitive,
        val p20: NullablePrimitive,
        val p21: NullablePrimitive,
        val p22: NullablePrimitive,
        val p23: NullablePrimitive,
        val p24: NullablePrimitive,
        val p25: NullablePrimitive,
        val p26: NullablePrimitive,
        val p27: NullablePrimitive,
        val p28: NullablePrimitive,
        val p29: NullablePrimitive,
        val p30: NullablePrimitive,
        val p31: NullablePrimitive,
        val p32: NullablePrimitive
    )

    @Test
    fun test33() {
        val expected = callPrimaryConstructor<Dst33> { NullablePrimitive(it.index) }
        val src = defaultMapper.writeValueAsString(expected)
        Assertions.assertEquals(expected, defaultMapper.readValue<Dst33>(src))
    }

    data class Dst64(
        val p00: NullablePrimitive,
        val p01: NullablePrimitive,
        val p02: NullablePrimitive,
        val p03: NullablePrimitive,
        val p04: NullablePrimitive,
        val p05: NullablePrimitive,
        val p06: NullablePrimitive,
        val p07: NullablePrimitive,
        val p08: NullablePrimitive,
        val p09: NullablePrimitive,
        val p10: NullablePrimitive,
        val p11: NullablePrimitive,
        val p12: NullablePrimitive,
        val p13: NullablePrimitive,
        val p14: NullablePrimitive,
        val p15: NullablePrimitive,
        val p16: NullablePrimitive,
        val p17: NullablePrimitive,
        val p18: NullablePrimitive,
        val p19: NullablePrimitive,
        val p20: NullablePrimitive,
        val p21: NullablePrimitive,
        val p22: NullablePrimitive,
        val p23: NullablePrimitive,
        val p24: NullablePrimitive,
        val p25: NullablePrimitive,
        val p26: NullablePrimitive,
        val p27: NullablePrimitive,
        val p28: NullablePrimitive,
        val p29: NullablePrimitive,
        val p30: NullablePrimitive,
        val p31: NullablePrimitive,
        val p32: NullablePrimitive,
        val p33: NullablePrimitive,
        val p34: NullablePrimitive,
        val p35: NullablePrimitive,
        val p36: NullablePrimitive,
        val p37: NullablePrimitive,
        val p38: NullablePrimitive,
        val p39: NullablePrimitive,
        val p40: NullablePrimitive,
        val p41: NullablePrimitive,
        val p42: NullablePrimitive,
        val p43: NullablePrimitive,
        val p44: NullablePrimitive,
        val p45: NullablePrimitive,
        val p46: NullablePrimitive,
        val p47: NullablePrimitive,
        val p48: NullablePrimitive,
        val p49: NullablePrimitive,
        val p50: NullablePrimitive,
        val p51: NullablePrimitive,
        val p52: NullablePrimitive,
        val p53: NullablePrimitive,
        val p54: NullablePrimitive,
        val p55: NullablePrimitive,
        val p56: NullablePrimitive,
        val p57: NullablePrimitive,
        val p58: NullablePrimitive,
        val p59: NullablePrimitive,
        val p60: NullablePrimitive,
        val p61: NullablePrimitive,
        val p62: NullablePrimitive,
        val p63: NullablePrimitive
    )

    @Test
    fun test64() {
        val expected = callPrimaryConstructor<Dst64> { NullablePrimitive(it.index) }
        val src = defaultMapper.writeValueAsString(expected)
        Assertions.assertEquals(expected, defaultMapper.readValue<Dst64>(src))
    }

    data class Dst65(
        val p00: NullablePrimitive,
        val p01: NullablePrimitive,
        val p02: NullablePrimitive,
        val p03: NullablePrimitive,
        val p04: NullablePrimitive,
        val p05: NullablePrimitive,
        val p06: NullablePrimitive,
        val p07: NullablePrimitive,
        val p08: NullablePrimitive,
        val p09: NullablePrimitive,
        val p10: NullablePrimitive,
        val p11: NullablePrimitive,
        val p12: NullablePrimitive,
        val p13: NullablePrimitive,
        val p14: NullablePrimitive,
        val p15: NullablePrimitive,
        val p16: NullablePrimitive,
        val p17: NullablePrimitive,
        val p18: NullablePrimitive,
        val p19: NullablePrimitive,
        val p20: NullablePrimitive,
        val p21: NullablePrimitive,
        val p22: NullablePrimitive,
        val p23: NullablePrimitive,
        val p24: NullablePrimitive,
        val p25: NullablePrimitive,
        val p26: NullablePrimitive,
        val p27: NullablePrimitive,
        val p28: NullablePrimitive,
        val p29: NullablePrimitive,
        val p30: NullablePrimitive,
        val p31: NullablePrimitive,
        val p32: NullablePrimitive,
        val p33: NullablePrimitive,
        val p34: NullablePrimitive,
        val p35: NullablePrimitive,
        val p36: NullablePrimitive,
        val p37: NullablePrimitive,
        val p38: NullablePrimitive,
        val p39: NullablePrimitive,
        val p40: NullablePrimitive,
        val p41: NullablePrimitive,
        val p42: NullablePrimitive,
        val p43: NullablePrimitive,
        val p44: NullablePrimitive,
        val p45: NullablePrimitive,
        val p46: NullablePrimitive,
        val p47: NullablePrimitive,
        val p48: NullablePrimitive,
        val p49: NullablePrimitive,
        val p50: NullablePrimitive,
        val p51: NullablePrimitive,
        val p52: NullablePrimitive,
        val p53: NullablePrimitive,
        val p54: NullablePrimitive,
        val p55: NullablePrimitive,
        val p56: NullablePrimitive,
        val p57: NullablePrimitive,
        val p58: NullablePrimitive,
        val p59: NullablePrimitive,
        val p60: NullablePrimitive,
        val p61: NullablePrimitive,
        val p62: NullablePrimitive,
        val p63: NullablePrimitive,
        val p64: NullablePrimitive
    )

    @Test
    fun test65() {
        val expected = callPrimaryConstructor<Dst65> { NullablePrimitive(it.index) }
        val src = defaultMapper.writeValueAsString(expected)
        Assertions.assertEquals(expected, defaultMapper.readValue<Dst65>(src))
    }

    // It cannot be a data class because the generated method would exceed the argument size limit.
    class DstMax(
        val p000: NullablePrimitive,
        val p001: NullablePrimitive,
        val p002: NullablePrimitive,
        val p003: NullablePrimitive,
        val p004: NullablePrimitive,
        val p005: NullablePrimitive,
        val p006: NullablePrimitive,
        val p007: NullablePrimitive,
        val p008: NullablePrimitive,
        val p009: NullablePrimitive,
        val p010: NullablePrimitive,
        val p011: NullablePrimitive,
        val p012: NullablePrimitive,
        val p013: NullablePrimitive,
        val p014: NullablePrimitive,
        val p015: NullablePrimitive,
        val p016: NullablePrimitive,
        val p017: NullablePrimitive,
        val p018: NullablePrimitive,
        val p019: NullablePrimitive,
        val p020: NullablePrimitive,
        val p021: NullablePrimitive,
        val p022: NullablePrimitive,
        val p023: NullablePrimitive,
        val p024: NullablePrimitive,
        val p025: NullablePrimitive,
        val p026: NullablePrimitive,
        val p027: NullablePrimitive,
        val p028: NullablePrimitive,
        val p029: NullablePrimitive,
        val p030: NullablePrimitive,
        val p031: NullablePrimitive,
        val p032: NullablePrimitive,
        val p033: NullablePrimitive,
        val p034: NullablePrimitive,
        val p035: NullablePrimitive,
        val p036: NullablePrimitive,
        val p037: NullablePrimitive,
        val p038: NullablePrimitive,
        val p039: NullablePrimitive,
        val p040: NullablePrimitive,
        val p041: NullablePrimitive,
        val p042: NullablePrimitive,
        val p043: NullablePrimitive,
        val p044: NullablePrimitive,
        val p045: NullablePrimitive,
        val p046: NullablePrimitive,
        val p047: NullablePrimitive,
        val p048: NullablePrimitive,
        val p049: NullablePrimitive,
        val p050: NullablePrimitive,
        val p051: NullablePrimitive,
        val p052: NullablePrimitive,
        val p053: NullablePrimitive,
        val p054: NullablePrimitive,
        val p055: NullablePrimitive,
        val p056: NullablePrimitive,
        val p057: NullablePrimitive,
        val p058: NullablePrimitive,
        val p059: NullablePrimitive,
        val p060: NullablePrimitive,
        val p061: NullablePrimitive,
        val p062: NullablePrimitive,
        val p063: NullablePrimitive,
        val p064: NullablePrimitive,
        val p065: NullablePrimitive,
        val p066: NullablePrimitive,
        val p067: NullablePrimitive,
        val p068: NullablePrimitive,
        val p069: NullablePrimitive,
        val p070: NullablePrimitive,
        val p071: NullablePrimitive,
        val p072: NullablePrimitive,
        val p073: NullablePrimitive,
        val p074: NullablePrimitive,
        val p075: NullablePrimitive,
        val p076: NullablePrimitive,
        val p077: NullablePrimitive,
        val p078: NullablePrimitive,
        val p079: NullablePrimitive,
        val p080: NullablePrimitive,
        val p081: NullablePrimitive,
        val p082: NullablePrimitive,
        val p083: NullablePrimitive,
        val p084: NullablePrimitive,
        val p085: NullablePrimitive,
        val p086: NullablePrimitive,
        val p087: NullablePrimitive,
        val p088: NullablePrimitive,
        val p089: NullablePrimitive,
        val p090: NullablePrimitive,
        val p091: NullablePrimitive,
        val p092: NullablePrimitive,
        val p093: NullablePrimitive,
        val p094: NullablePrimitive,
        val p095: NullablePrimitive,
        val p096: NullablePrimitive,
        val p097: NullablePrimitive,
        val p098: NullablePrimitive,
        val p099: NullablePrimitive,
        val p100: NullablePrimitive,
        val p101: NullablePrimitive,
        val p102: NullablePrimitive,
        val p103: NullablePrimitive,
        val p104: NullablePrimitive,
        val p105: NullablePrimitive,
        val p106: NullablePrimitive,
        val p107: NullablePrimitive,
        val p108: NullablePrimitive,
        val p109: NullablePrimitive,
        val p110: NullablePrimitive,
        val p111: NullablePrimitive,
        val p112: NullablePrimitive,
        val p113: NullablePrimitive,
        val p114: NullablePrimitive,
        val p115: NullablePrimitive,
        val p116: NullablePrimitive,
        val p117: NullablePrimitive,
        val p118: NullablePrimitive,
        val p119: NullablePrimitive,
        val p120: NullablePrimitive,
        val p121: NullablePrimitive,
        val p122: NullablePrimitive,
        val p123: NullablePrimitive,
        val p124: NullablePrimitive,
        val p125: NullablePrimitive,
        val p126: NullablePrimitive,
        val p127: NullablePrimitive,
        val p128: NullablePrimitive,
        val p129: NullablePrimitive,
        val p130: NullablePrimitive,
        val p131: NullablePrimitive,
        val p132: NullablePrimitive,
        val p133: NullablePrimitive,
        val p134: NullablePrimitive,
        val p135: NullablePrimitive,
        val p136: NullablePrimitive,
        val p137: NullablePrimitive,
        val p138: NullablePrimitive,
        val p139: NullablePrimitive,
        val p140: NullablePrimitive,
        val p141: NullablePrimitive,
        val p142: NullablePrimitive,
        val p143: NullablePrimitive,
        val p144: NullablePrimitive,
        val p145: NullablePrimitive,
        val p146: NullablePrimitive,
        val p147: NullablePrimitive,
        val p148: NullablePrimitive,
        val p149: NullablePrimitive,
        val p150: NullablePrimitive,
        val p151: NullablePrimitive,
        val p152: NullablePrimitive,
        val p153: NullablePrimitive,
        val p154: NullablePrimitive,
        val p155: NullablePrimitive,
        val p156: NullablePrimitive,
        val p157: NullablePrimitive,
        val p158: NullablePrimitive,
        val p159: NullablePrimitive,
        val p160: NullablePrimitive,
        val p161: NullablePrimitive,
        val p162: NullablePrimitive,
        val p163: NullablePrimitive,
        val p164: NullablePrimitive,
        val p165: NullablePrimitive,
        val p166: NullablePrimitive,
        val p167: NullablePrimitive,
        val p168: NullablePrimitive,
        val p169: NullablePrimitive,
        val p170: NullablePrimitive,
        val p171: NullablePrimitive,
        val p172: NullablePrimitive,
        val p173: NullablePrimitive,
        val p174: NullablePrimitive,
        val p175: NullablePrimitive,
        val p176: NullablePrimitive,
        val p177: NullablePrimitive,
        val p178: NullablePrimitive,
        val p179: NullablePrimitive,
        val p180: NullablePrimitive,
        val p181: NullablePrimitive,
        val p182: NullablePrimitive,
        val p183: NullablePrimitive,
        val p184: NullablePrimitive,
        val p185: NullablePrimitive,
        val p186: NullablePrimitive,
        val p187: NullablePrimitive,
        val p188: NullablePrimitive,
        val p189: NullablePrimitive,
        val p190: NullablePrimitive,
        val p191: NullablePrimitive,
        val p192: NullablePrimitive,
        val p193: NullablePrimitive,
        val p194: NullablePrimitive,
        val p195: NullablePrimitive,
        val p196: NullablePrimitive,
        val p197: NullablePrimitive,
        val p198: NullablePrimitive,
        val p199: NullablePrimitive,
        val p200: NullablePrimitive,
        val p201: NullablePrimitive,
        val p202: NullablePrimitive,
        val p203: NullablePrimitive,
        val p204: NullablePrimitive,
        val p205: NullablePrimitive,
        val p206: NullablePrimitive,
        val p207: NullablePrimitive,
        val p208: NullablePrimitive,
        val p209: NullablePrimitive,
        val p210: NullablePrimitive,
        val p211: NullablePrimitive,
        val p212: NullablePrimitive,
        val p213: NullablePrimitive,
        val p214: NullablePrimitive,
        val p215: NullablePrimitive,
        val p216: NullablePrimitive,
        val p217: NullablePrimitive,
        val p218: NullablePrimitive,
        val p219: NullablePrimitive,
        val p220: NullablePrimitive,
        val p221: NullablePrimitive,
        val p222: NullablePrimitive,
        val p223: NullablePrimitive,
        val p224: NullablePrimitive,
        val p225: NullablePrimitive,
        val p226: NullablePrimitive,
        val p227: NullablePrimitive,
        val p228: NullablePrimitive,
        val p229: NullablePrimitive,
        val p230: NullablePrimitive,
        val p231: NullablePrimitive,
        val p232: NullablePrimitive,
        val p233: NullablePrimitive,
        val p234: NullablePrimitive,
        val p235: NullablePrimitive,
        val p236: NullablePrimitive,
        val p237: NullablePrimitive,
        val p238: NullablePrimitive,
        val p239: NullablePrimitive,
        val p240: NullablePrimitive,
        val p241: NullablePrimitive,
        val p242: NullablePrimitive,
        val p243: NullablePrimitive,
        val p244: NullablePrimitive,
        val p245: NullablePrimitive,
        val p246: NullablePrimitive,
        val p247: NullablePrimitive,
        val p248: NullablePrimitive,
        val p249: NullablePrimitive,
        val p250: NullablePrimitive,
        val p251: NullablePrimitive,
        val p252: NullablePrimitive
    )

    @Test
    fun testMax() {
        val expected = callPrimaryConstructor<DstMax> { NullablePrimitive(it.index) }
        val src = defaultMapper.writeValueAsString(expected)
        assertReflectEquals(expected, defaultMapper.readValue<DstMax>(src))
    }
}
